package org.example.route.service.impl;


import lombok.extern.slf4j.Slf4j;
import org.example.route.constant.OrderConstant;
import org.example.route.constant.PriceConstant;
import org.example.route.constant.ShoppingConstant;
import org.example.route.constant.TrainConstant;
import org.example.route.event.publisher.OrderPublisher;
import org.example.route.event.source.OrderPaySource;
import org.example.route.mapper.*;
import org.example.route.model.dto.OrderGenerateDTO;
import org.example.route.model.dto.PayOrderDTO;
import org.example.route.model.dto.PriceQueryDTO;
import org.example.route.model.pojo.*;
import org.example.route.model.vo.IntoDetailVO;
import org.example.route.model.vo.PriceVO;
import org.example.route.model.vo.StationShowVO;
import org.example.route.service.BuyService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Slf4j
public class BuyServiceImpl implements BuyService {
    @Autowired
    private StationMapper stationMapper;
    @Autowired
    private StationRouteMapper stationRouteMapper;
    @Autowired
    private PriceMapper priceMapper;
    @Autowired
    private TrainMapper trainMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private SeatMapper seatMapper;
    @Autowired
    private CarriageMapper carriageMapper;
    @Autowired
    private ShoppingMapper shoppingMapper;
    @Autowired
    private OrderPublisher orderPublisher;

    private final ConcurrentHashMap<Long, Object> orderLocks = new ConcurrentHashMap<>();
    DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    @Override
    public IntoDetailVO intoDetail(PriceQueryDTO priceQueryDTO) {
        //查对应的站点起始站
        List<Station> stations1 = stationMapper.getByCityId(priceQueryDTO.getCityId1());
        //查对应的站点到达站
        List<Station> stations2 = stationMapper.getByCityId(priceQueryDTO.getCityId2());

        //传给前端的显示站点的集合
        List<StationShowVO> stationShowVOList1 = new ArrayList<>();
        List<StationShowVO> stationShowVOList2 = new ArrayList<>();

        //获得所有起始站点
        List<StationRoute> stationRoutesStart = new ArrayList<>();
        //获得所有到达站点
        List<StationRoute> stationRoutesTarget = new ArrayList<>();

        List<PriceVO> priceVOs = new ArrayList<>();

        for (Station station1 : stations1)
        {
            StationShowVO stationShowVO = new StationShowVO();
            BeanUtils.copyProperties(station1,stationShowVO);
            stationShowVOList1.add(stationShowVO);
            //cityName在这里可以不加
            priceQueryDTO.setStationId1(station1.getId());

            List<StationRoute> stationRoutesStart1 = stationRouteMapper.getStartByPriceDTO(priceQueryDTO);

            stationRoutesStart.addAll(stationRoutesStart1);

        }

        for (Station station2 : stations2)
        {
            StationShowVO stationShowVO = new StationShowVO();
            BeanUtils.copyProperties(station2,stationShowVO);
            stationShowVOList2.add(stationShowVO);
            priceQueryDTO.setStationId2(station2.getId());
            List<StationRoute> stationRoutesTarget1 = stationRouteMapper.getTargetByPriceDTO(priceQueryDTO);
            stationRoutesTarget.addAll(stationRoutesTarget1);
        }

//整理所有的起始点和目标点，找到可以连成一条线的路线
        for (StationRoute stationRouteStart : stationRoutesStart)
            for (StationRoute stationRouteTarget : stationRoutesTarget)
            {
                if (stationRouteStart.getRouteId().equals(stationRouteTarget.getRouteId()) && stationRouteStart.getTrainId().equals(stationRouteTarget.getTrainId())
                        && stationRouteStart.getSequence() < stationRouteTarget.getSequence()
                ){
                    //表示成立
                    List<Price> prices = priceMapper.getByDoubleIdsAndGrade(stationRouteStart.getId(), stationRouteTarget.getId(), priceQueryDTO.getGrade());
                    log.info("所有价格列表===========================================================,{}", prices);
                    LocalDateTime endTime = stationRouteTarget.getGoTime();
                    LocalDateTime startTime = stationRouteStart.getArrivalTime();
                    String goName1 = stationMapper.getNameById(stationRouteStart.getStationId());
                    String goName2 = stationMapper.getNameById(stationRouteTarget.getStationId());
                    String gradeName;
                    Long trainId = stationRouteStart.getTrainId();
                    String trainSerialNumber = trainMapper.getSerialById(trainId);

                    if(!prices.isEmpty()) {
                        if (trainMapper.getKindById(stationRouteStart.getTrainId()).equals(TrainConstant.KIND_ORDINARY)) {
                            gradeName = prices.get(0).getGrade().equals(PriceConstant.GRADE_HIGH) ? "软卧" : prices.get(0).getGrade().equals(PriceConstant.GRADE_MIDDLE) ? "硬卧" : "硬座";
                        } else {
                            gradeName = prices.get(0).getGrade().equals(PriceConstant.GRADE_HIGH) ? "商务座" : prices.get(0).getGrade().equals(PriceConstant.GRADE_MIDDLE) ? "一等座" : " 二等座";
                        }

                        for (Price price : prices)
                        {
                            PriceVO priceVO = new PriceVO();
                            BeanUtils.copyProperties(price,priceVO);
                            priceVO.setGoName1(goName1);
                            priceVO.setGoName2(goName2);
                            priceVO.setGradeName(gradeName);
                            priceVO.setEndTime(sdf.format(endTime));
                            priceVO.setStartTime(sdf.format(startTime));
                            priceVO.setTrainId(trainId);
                            priceVO.setTrainSerialNumber(trainSerialNumber);
                            priceVOs.add(priceVO);

                        }
                    }




                }
            }

        IntoDetailVO intoDetailVO = new IntoDetailVO();
        intoDetailVO.setPriceVOList(priceVOs);
        intoDetailVO.setStartStationShowVOList(stationShowVOList1);
        intoDetailVO.setTargetStationShowVOList(stationShowVOList2);
        return intoDetailVO;

    }

    //生成订单和购物车的代码
    //重构这一块
    @Override
    public void generateOrderAndShopping(OrderGenerateDTO orderGenerateDTO) {
        Order order = new Order();

        Price price = priceMapper.getById(orderGenerateDTO.getPriceId());
        if(price.getLastCount() <= 0)
        {
            throw new RuntimeException("票已售罄！");
        }

        BeanUtils.copyProperties(orderGenerateDTO,order);
        order.setStatus(OrderConstant.WAIT_PAY);
        order.setCreateTime(LocalDateTime.now());



//        //票的容量减少一张
//        priceMapper.bePayed(orderGenerateDTO.getPriceId());
//        //该座位显示被占，该车厢的容量减少一个
//        seatMapper.beOccupied(orderGenerateDTO.getSeatId());
//        carriageMapper.beOccupied(seatMapper.getCarriageIdById(orderGenerateDTO.getSeatId()));
//
//        Shopping  shopping = new Shopping();
//        shopping.setOrderId(order.getId());
//        //设置订单等待支付的状态
//
//        shopping.setPay(ShoppingConstant.UN_SELECT);

//        shoppingMapper.add(shopping);

        //上锁
        Object lock = orderLocks.computeIfAbsent(orderGenerateDTO.getPriceId(), k -> new Object());
        synchronized (lock) {
            orderMapper.add(order);

            //装配发布者
            OrderPaySource orderPaySource = new OrderPaySource();
            BeanUtils.copyProperties(order, orderPaySource);
            orderPublisher.publishPayEvent(orderPaySource);


        }

    }

    //支付订单的代码
    @Override
    public void payOrder(PayOrderDTO payOrderDTO) {



             Order order = orderMapper.getById(payOrderDTO.getOrderId());
             order.setStatus(OrderConstant.PAYED);
             order.setCreateTime(LocalDateTime.now());
             orderMapper.update( order);




    }



}
